#include "cgzCSpdLog.h"

#include <spdlog/spdlog.h>
#include <spdlog/version.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/daily_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>

std::atomic<int> s_fid = 0;
const char *logKeys[] = {
    "a",
    "b",
    "c",
    "d",
    "e",
    "f",
    "g",
    "h",
    "i",
    "j",
    "k",
    "l",
    "m",
    "n",
    "o",
    "p",
    "q",
    "r",
    "s",
    "t",
    "u",
    "v",
    "w",
    "x",
    "y",
    "z"};

cgzCSpdItem::cgzCSpdItem(const u_int8_t fid, const u_int8_t flg, std::string &msg)
    : m_fid(fid), m_flg(flg), m_msg(std::move(msg))
{
}

cgzCSpdItem::~cgzCSpdItem()
{
    m_fid = -1;
    m_flg = -1;
    m_msg.clear();
}

cgzCSpdLog::cgzCSpdLog(cgzCThreadPool *pool, const char *name)
    : cgzITask(pool, name, cgzETask::CSpdLog)
{
    std::string date = get_current_date();
    m_dir = "logs/" + date;
    // 创建目录
    std::filesystem::create_directories(m_dir);
}

cgzCSpdLog::~cgzCSpdLog()
{
    spdlog::drop_all();
}

bool cgzCSpdLog::run(int64_t nms)
{
    while (!m_runTask.empty())
    {
        auto item = static_cast<cgzCSpdItem *>(m_runTask.front());
        m_runTask.pop_front();
        auto logger = spdlog::get(logKeys[item->m_fid]);
        switch (item->m_flg)
        {
        case spdlog::level::trace:
            logger->trace(item->m_msg.c_str());
            break;
        case spdlog::level::debug:
            logger->debug(item->m_msg.c_str());
            break;
        case spdlog::level::info:
            logger->info(item->m_msg.c_str());
            break;
        case spdlog::level::warn:
            logger->warn(item->m_msg.c_str());
            break;
        case spdlog::level::err:
            logger->error(item->m_msg.c_str());
            break;
        case spdlog::level::critical:
            logger->critical(item->m_msg.c_str());
            break;
        default:
            break;
        }
        // 要退出进程了
        logger->flush();
        item->~cgzCSpdItem();
    }
    return true;
}

uint8_t cgzCSpdLog::Customize(const char *fname, bool outconsole)
{
    // 设置日志文件路径
    std::string log_file_path = m_dir + "/" + fname + ".log";

    // 创建文件日志记录器
    auto file_sink = std::make_shared<spdlog::sinks::daily_file_sink_mt>(log_file_path, 0, 0);

    // 创建 logger
    const char *key = logKeys[s_fid];

    // 创建一个 sink 列表
    std::vector<spdlog::sink_ptr> sinks;
    sinks.push_back(file_sink); // 添加文件 sink

    // 如果 outconsole 为 true，则添加控制台 sink
    if (outconsole)
    {
        auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
        sinks.push_back(console_sink); // 添加控制台 sink
    }

    // 创建 logger，并将所有 sink 添加到 logger
    auto logger = std::make_shared<spdlog::logger>(key, sinks.begin(), sinks.end());

    // 设置日志格式
    logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");

    // 注册 logger
    spdlog::register_logger(logger);

    // 设置日志级别
    logger->set_level(spdlog::level::trace);
    return s_fid++;
}
